const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
    #state = PENDING
    #result = undefined
    #handlers = []

    constructor(executor) {
        const resolve = (data) => {
            this.#changeState(FULFILLED, data)
        }
        const reject = (reason) => {
            this.#changeState(REJECTED, reason)
        }
        try{
            executor(resolve, reject)
        }
        catch(err) {
            reject(err)
        }  //无法捕获异步错误
        
    }

    #changeState(state, result) {
        if(this.#state !== PENDING) return
        this.#state = state
        this.#result = result
        this.#run()
    }

    #isPromise(value) {
      return (
          value !== null &&
          (typeof value === 'object' || typeof value === 'function') &&
          typeof value.then === 'function'
      )
    }

    #runMicroTask(func) {
        // node环境
        // process.nextTick(func)
        if (typeof process !== 'underfined' && typeof process.nextTick === 'function') {
            return process.nextTick(func)
        } else if (typeof MutationObserver === 'function') {
            // 浏览器环境
            // MutationObserver
            const ob = new MutationObserver(func)
            const textNode = document.createTextNode()
            ob.observe(textNode, {
                characterData: true
            })
            textNode.data = '2'
        } else {
            setTimeout(func, 0)
        }
        
    }

    #runOne(callback, resolve, reject) {
        //this.#runMicroTask(() => {
            if (typeof callback !== 'function') {
                const settled = this.#state === FULFILLED ? resolve : reject
                settled(this.#result)
                return
            }
            try {
                const data = callback(this.#result)
                if (this.#isPromise(data)) {
                    data.then(resolve, reject)
                } else {
                    resolve(data)
                }
            } catch (err) {
                reject(err)
            }
        //})
    }

    #run() {
        if (this.#state === PENDING) return
        while (this.#handles.length) {
            const { onFulfilled, onRejected, resolve, reject } = this.#handlers.shift()
            if (this.#state === FULFILLED) {
                this.#runOne(onFulfilled, resolve, reject)
            } else {
                this.#runOne(onRejected, resolve, reject)
            }
        }
    }

    then(onFulfilled, onRejected) {
        return new MyPromise((resolve, reject) => {
            this.#handlers.push({
             onFulfilled,
             onRejected,
             resolve,
             reject
            })
            this.#run()
        })
    }
}

Promise.myAll = function(proms){
    let res, rej
    const p = new Promise((resolve, reject)=>{
        res = resolve
        rej = reject
    })
    let i = 0
    let fulfilled = 0
    const result = []
    for (let prom of proms) {
        const index = i
        i++
        Promise.resolve(prom).then((data)=>{
            //1.把完成的数据汇总到最终结果
            result[index] = data
            //2.判定是否全部完成
            fulfilled++
            if (fulfilled === i) {
                res(result)
            }
        }, rej)
    }
    if (i === 0) {
        res([])
    }
    return p;
}